package com.bjsxt;



public class MySinglyLinkedList01<E> implements MyList01<E> {
    /*内部类的总结：为了更好地隐藏。作用：当一些类型不具备通用性时
     * 或者是只能在某一个对象当中使用时，是这个对象所独有的*/
    //定义单向链表中的节点对象
    //因为要在类中节点象存放元素，元素是有类型的，所以定义泛型类型
    class Node1<E>{
        //记录元素的成员变量  记录节点地址的成员变量（单向链表所以一个节点就足够）
        private E item;//存储元素
        private Node1 next;//存储节点地址 因为下一个节点的对象也是Node类型
        //构造方法，方便传递数据
        Node1(E item,Node1 next){
            this.item=item;
            this.next=next;
        }

    }

    private Node1 head;//存放链表中的头节点
    private int size;//记录元素个数
    //添加元素
    @Override
    public void add(E element) {
        //创建节点
        Node1<E> node1 = new Node1<>(element,null);
        //尾节点  通过头找到尾
        Node1 tail = getTail();
        //节点挂接
        if(tail == null){
            this.head=node1;
        }else {
            tail.next=node1;
        }
        //记录元素个数
        this.size++;
    }
    //找尾节点
    private Node1 getTail(){
        //头节点是否存在
        if(this.head==null){
            return null;
        }
        //查找尾节点
        Node1 node1 = this.head;
        while(true){
            if(node1.next==null)break;
            //通过当前节点的next，获取下一个节点
            node1 = node1.next;//节点移动，指向下一个节点
        }
        return node1;
    }
    //根据元素位置获取元素
    @Override
    public E get(int index) {
        //校检index合法性
        this.checkedIndex(index);
        //获取节点
       Node1<E> node1 =  this.getNode1(index);
        //从节点中获取元素

        return node1.item;
    }
    //校检index合法性
    private void checkedIndex(int index){
        if(!(index>=0 && index<this.size)){
            throw new IndexOutOfBoundsException("Index:"+index+"Size:"+this.size);
        }
    }
    //根据位置获取节点  有返回值
    private Node1 getNode1(int index){
        Node1<E> node1 = this.head;
        for(int i=0;i<index;i++){
            node1=node1.next;
        }
        return node1;
    }
    //获取元素个数
    @Override
    public int size() {
        return this.size;
    }
    //根据元素位置删除元素
    @Override
    public E remove(int index) {
        //校检Index的合法性
        this.checkedIndex(index);
        //根据位置找到该节点 对象
        Node1<E> node1 =this.getNode1(index);
        //获取该节点对象的 元素
         E item = node1.item;
        //将该节点对象从单向链表中移除
        //如果头节点是被删除的节点，将头指针向下移一位节点为头节点
        if(this.head==node1){
            this.head=node1.next;
        }else {
            Node1<E> temp = this.head;
            for(int i=0;i<index-1;i++){
                temp = temp.next;
            }
            temp.next = node1.next;
        }
        //记录元素个数
        this.size--;
        //将该元素返回
        return item;
    }

    public static void main(String[] args) {
        MySinglyLinkedList01<String> msl = new MySinglyLinkedList01<>();
        msl.add("2");
        msl.add("3");
        msl.add("5");
        msl.add("1");
        msl.add("4");
        System.out.println(msl.size);
        System.out.println(msl.remove(0));
        for (int i=0;i< msl.size;i++){
            System.out.println(msl.get(i));
        }
    }
}
